/*-------------------------------------------------------------------------
 - Copyright (c) 2024-2025 [XD-AMCC TEAM]
 - [XD-AMCC] is licensed under Mulan PSL v2.
 - You can use this software according to the terms and conditions of the Mulan PSL v2.
 - You may obtain a copy of Mulan PSL v2 at:
 -          http://license.coscl.org.cn/MulanPSL2
 - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
 - OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 - TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 - See the Mulan PSL v2 for more details.
 ------------------------------------------------------------------------*/


/**
 * @file
 * @brief Interface of class IR-codes emitter.
 *
 * @author  WXQ#XDU
 * @date    2025.01
 */

#pragma once

#ifndef AMCC_IRCODE_H
#define AMCC_IRCODE_H

#include "tree.h"
#include "symtable.h"

AMCC_DECL_BEGIN



// -----------------------------------------------------------------------
/// @name API of class emitter
/// @{


/** Class emitter for IR-codes generation */
typedef struct ircode_emitter t_emitter, * t_emitter_ptr;


/**
 * @brief Creates and initializes a new emitter for IR-codes generation.
 *
 * @param pParseTreeRoot  pointer to the complete parse tree
 * @param pSymTableRoot   pointer to the complete symbol-table tree
 *
 * @return On success, return a pointer to the new emitter.
 * @return On failure, return null.
 */
extern t_emitter_ptr ircode_emitter_new(t_tree_ptr     pParseTreeRoot,
                                        t_symtable_ptr pSymTableRoot);

/**
 * @brief Destroys the emitter and releases all inner resource.
 * @param pThis    pointer to this emitter
 */
extern void ircode_emitter_destroy(t_emitter_ptr pThis);

/**
 * @brief  Perform ir-codes generation.
 *
 * @param pThis  pointer to this emitter
 * @return Return 0 on success, and return negative value on failure.
 *   <br/> Return -1 on empty input;
 *   <br/> Return -2 on other errors.
 */
extern int  ircode_emitter_run(t_emitter_ptr pThis);


/**
 * @brief  Get the number of errors during ir-codes generation.
 *
 * @param pThis  pointer to this emitter
 * @return the number of errors.
 */
extern int ircode_emitter_errors(t_emitter_ptr pThis);



/**
 * @brief  A  func-code pair represents all IR-codes of a function
 *         in source program.
 *
 * For any global or nested function, the field "declNode" is the parse
 *     tree node marked by non-terminal "funcDeclaration".
 * For whole translation unit, the field "declNode" is the parse
 *     tree node marked by non-terminal "translationUnit".
 */
typedef struct  func_ircode_pair {
    t_tree_ptr   declNode;  //!< parse tree node
    t_list_ptr   codes;     //!< IR-codes
} t_func_code_pair ;


/**
 * A type alias of whole IR-codes for source program, and
 *   the underlying type is list&lt;t_func_code_pair*&gt;.
 */
typedef t_list_ptr  t_program_codes;


/**
 * @brief Get the whole IR-codes for source program
 *        and change ownership to caller.
 *
 * @param pThis  pointer to the IR-code emitter
 * @return  Return the IR-codes for source program.
 *
 * @note After call this function, caller MUST destroy the returned data
 *       by ircodes_destroy().
 */
extern t_program_codes  ircode_emitter_GRAB(t_emitter_ptr pThis);

/**
 * @brief  Destroy whole IR-codes for source program.
 *
 * @param programCodes list of all func_code_pairs in source program
 */
#define ircodes_destroy(programCodes)   codemgr_destroy_codes(programCodes)

extern void codemgr_destroy_codes(t_program_codes programCodes);

/**
 * @brief Dump ir-codes into a file.
 *
 * @param programCodes list of all func_code_pairs in source program
 */
extern void ircodes_dump(t_program_codes programCodes);

#define ircode_dump ircodes_dump


/// @}
// -----------------------------------------------------------------------



AMCC_DECL_END

#endif // #ifndef AMCC_IRCODE_H
